package com.ddatsh.transaction.core.lifecycle.executor;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ddatsh.transaction.core.exception.TransException;
import com.ddatsh.transaction.core.lifecycle.processunit.ProcessUnit;
import com.ddatsh.transaction.core.model.ApplicationErrorCode;
import com.ddatsh.transaction.core.model.Response;
import com.ddatsh.transaction.core.model.TransContext;
import com.ddatsh.transaction.core.provider.ExceptionDumpProvider;
import com.ddatsh.transaction.core.thread.NewThreaded;

/**
 * 请求主控制/执行单元，该模型用于处理交易请求
 * 
 * @author ddatsh
 */
public class TranscationExecutorImpl implements TranscationExecutor {
	private Logger logger = LoggerFactory
			.getLogger(TranscationExecutorImpl.class);
	private ExecutorService executor = Executors.newCachedThreadPool();
	private ExceptionDumpProvider exceptionDumpProvider;

	public ExceptionDumpProvider getExceptionDumpProvider() {
		return exceptionDumpProvider;
	}

	public void setExceptionDumpProvider(
			ExceptionDumpProvider exceptionDumpProvider) {
		this.exceptionDumpProvider = exceptionDumpProvider;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.ddatsh.transaction.core.lifecycle.executor.TranscationExecutor#
	 * doTranscation(com.ddatsh.transaction.core .model.TransContext)
	 */
	public void doTranscation(TransContext transContext) {
		ProcessUnit[] processUnits = transContext.getTransProcessUnits();
		if (processUnits == null) {
			transContext.setException(new TransException(
					ApplicationErrorCode.APP_CONTEXT_EXCEPTION,
					"not found processunit for trans code："
							+ transContext.getRequest().getRequestNo()));

			return;
		}
		for (ProcessUnit proccessUnit : processUnits) {
			try {
				if (proccessUnit instanceof NewThreaded) {
					executor.submit((NewThreaded) proccessUnit);
				} else {
					proccessUnit.execute(transContext);
				}
			} catch (TransException te) {
				logger.error("transcation execute exception!", te);
				exceptionDumpProvider.dump(transContext);
				transContext.setException(te);
				break;
			} catch (Exception ex) {
				logger.error("transcation execute exception!", ex);
				exceptionDumpProvider.dump(transContext);
				TransException te = new TransException(
						ApplicationErrorCode.EXCEPTION, ex.getMessage());
				transContext.setException(te);
				break;
			}

			Object processResult = proccessUnit.getResult();
			transContext.addProcessResults(proccessUnit.getName(),
					processResult);
			if (proccessUnit.isReturn()) {
				Response response = new Response(transContext.getRequest());
				response.setResponseBody(processResult);
				response.setErrorCode(ApplicationErrorCode.SUCCESS);
				response.setStatus(Response.STATUS_COMPLETE);
				transContext.setResponse(response);
			}
		}
	}
}
